package com.youjiang.meeting.controller;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;
import com.youjiang.meeting.po.Orders;
import com.youjiang.meeting.po.UserInfo;
import com.youjiang.meeting.service.OrderService;
import com.youjiang.meeting.service.UserService;
import com.youjiang.meeting.utils.ToolUtils;
import com.youjiang.meeting.utils.weixin.WeixinUtil;
import com.youjiang.meeting.utils.weixinpay.WXPayUtil;

import net.sf.json.JSONObject;

@Controller
public class WeiXinPay {
	
	@Autowired
	private OrderService oService;
	@Autowired
	private UserService userService;
	
	/**
     * 扫码支付  下单
     */
	@RequestMapping("wxPayUnifiedorder")
	@ResponseBody
	public String wxPayUnifiedorder(HttpServletRequest request,HttpSession session,int userid){
		JSONObject object = new JSONObject();
		
		UserInfo info = (UserInfo)session.getAttribute("userInfo");
		if(info==null){
			return ToolUtils.json(object, "00", "用户登录超时,请重新登录");
		}
		String total_fee="99";
		HashMap<String, String> data = new HashMap<String, String>();
        data.put("appid", WeixinUtil.APPID);
        data.put("mch_id", WeixinUtil.MCHID);
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("body", "微现场支付");
        data.put("out_trade_no", WXPayUtil.generateUUID());
        data.put("fee_type", "CNY");
        int price=((int)(Float.valueOf(total_fee)*100));
        data.put("total_fee", price+"");
        
        data.put("spbill_create_ip", request.getRemoteAddr());
        data.put("notify_url", WeixinUtil.NOTIFYURL);
        data.put("trade_type", "NATIVE");
        data.put("product_id", WXPayUtil.getCurrentTimestampMs()+((int)(Math.random()*5)+100)+"");
        try {
        	//key为商户平台设置的密钥key
        	String requestXML = WXPayUtil.generateSignedXml(data, "key");
        	String xml = WXPayUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
        	Map<String, String> result = WXPayUtil.xmlToMap(xml);
    		String return_code = result.get("return_code");
    		String return_msg = result.get("return_msg");
    		if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
    			/**
    			 * 将返回信息写到json中
    			 */
    			System.out.println(return_msg);
    			return ToolUtils.json(object, "01", "用户下单失败:"+return_msg);
    		}
    		String result_code = result.get("result_code");
    		if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
    			/**
    			 * 将返回信息写到json中
    			 */

    			System.out.println(return_msg);
    			return ToolUtils.json(object, "01", "用户下单失败:"+return_msg);
    		}

        	//获得二维码的url
        	String urlCode = (String) result.get("code_url"); 
        	String name = "payQRCode.png";
    		Boolean encode = com.youjiang.meeting.utils.weixinpay.ZxingKit.encode("http://blog.csdn.net/wangqiuyun/article/details/51241064", BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
    				PathKit.getWebRootPath()+File.separator+"view"+File.separator+name );
            //将二维码图片写入成功
    		if(encode){
            	//然后将name保存到request中
    			//最后转发到相应的页面，在该页面中可以根据<img alt="" src="<%=path %>/view/${payQRCode}">将二维码图片直接显示在页面上
    			Orders order = new Orders();
        		order.setUserid(userid);
        		order.setOutTradeNo(data.get("out_trade_no"));
        		order.setStatus(0);
        		order.setTotalFee(new BigDecimal(data.get("total_fee")));
        		order.setType(0);
        		oService.insertOrder(order);
        		
    			return ToolUtils.json(object, "10", name);
            }
    		
    	
    		System.out.println(urlCode);
        } catch (Exception e) {
            e.printStackTrace();
            return ToolUtils.json(object, "01", "用户下单失败:"+"请重新下单");
        }
		return ToolUtils.json(object, "01", "用户下单失败:"+"请重新下单");       
	}
	
	
	
	@RequestMapping("/weixin_notify")
	public void weixin_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
        
        //读取参数  
        InputStream inputStream ;  
        StringBuffer sb = new StringBuffer();  
        inputStream = request.getInputStream();  
        String s ;  
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
        while ((s = in.readLine()) != null){  
            sb.append(s);  
        }  
        in.close();  
        inputStream.close();  
  
        //解析xml成map  
        Map<String, String> m = new HashMap<String, String>();  
        m = WXPayUtil.xmlToMap(sb.toString());  
        //过滤空 设置 TreeMap  
        SortedMap<String,String> packageParams = new TreeMap<>();        
        Iterator it = m.keySet().iterator();  
        while (it.hasNext()) {  
            String parameter = (String) it.next();  
            String parameterValue = m.get(parameter);  
              
            String v = "";  
            if(null != parameterValue) {  
                v = parameterValue.trim();  
            }  
            packageParams.put(parameter, v);  
        }  
          
        // 账号信息  
        String key = "API_KEY"; // key  
  
        LoggerFactory.getLogger(WeiXinPay.class).info(packageParams.toString());  
        //判断签名是否正确  
        if(WXPayUtil.isSignatureValid(packageParams, key)){ 
            //------------------------------  
            //处理业务开始  
            //------------------------------  
            String resXml = "";  
            if("SUCCESS".equals((String)packageParams.get("result_code"))){  
                // 这里是支付成功  
                //////////执行自己的业务逻辑////////////////  
                String mch_id = (String)packageParams.get("mch_id");  
                String openid = (String)packageParams.get("openid");  
                String is_subscribe = (String)packageParams.get("is_subscribe");  
                String out_trade_no = (String)packageParams.get("out_trade_no");  
                BigDecimal bigDecimal = new BigDecimal(out_trade_no);  
                String total_fee = (String)packageParams.get("total_fee");  
                  
                LoggerFactory.getLogger(WeiXinPay.class).info("mch_id:"+mch_id);  
                LoggerFactory.getLogger(WeiXinPay.class).info("openid:"+openid);  
                LoggerFactory.getLogger(WeiXinPay.class).info("is_subscribe:"+is_subscribe);  
                LoggerFactory.getLogger(WeiXinPay.class).info("out_trade_no:"+out_trade_no);  
                LoggerFactory.getLogger(WeiXinPay.class).info("total_fee:"+total_fee);  
                  
                //////////执行自己的业务逻辑////////////////  
        		// 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        		// 避免已经成功、关闭、退款的订单被再次更新
                /**
                 * 根据out_trade_no查询用户订单状态
                 */
                Orders order = oService.findOrderByOut_trade_no(out_trade_no);
                if(order!=null){
                	if(order.getStatus()==0){
                		if((order.getTotalFee().equals(bigDecimal))){
                			order.setStatus(1);
                    		oService.updateOrder(order);
                		}
                		
                	}
                }else{
                	
                }
                /**
                 * 用户支付成功后将有效时间设置为1年
                 */
                Date beginDate = new Date();	
    			Calendar date = Calendar.getInstance();
    			date.setTime(beginDate);
    			DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
    			date.set(Calendar.DATE, date.get(Calendar.DATE) +365);
    			Date endDate = dft.parse(dft.format(date.getTime()));
    			String time = dft.format(endDate);
    			UserInfo info = userService.findUserByUserId(order.getUserid());
    			if(info!=null){
    				userService.updateResgisterTime(info.getId(), time);
    			}
    			
                LoggerFactory.getLogger(WeiXinPay.class).info("支付成功");  
                //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.  
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  
                  
            } else {  
            	LoggerFactory.getLogger(WeiXinPay.class).info("支付失败,错误信息：" + packageParams.get("err_code"));  
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";  
            }  
            //------------------------------  
            //处理业务完毕  
            //------------------------------  
            BufferedOutputStream out = new BufferedOutputStream(  
                    response.getOutputStream());  
            out.write(resXml.getBytes());  
            out.flush();  
            out.close();  
        } else{  
        	LoggerFactory.getLogger(WeiXinPay.class).info("通知签名验证失败");  
        }  
          
    }  
	

}
